import * as React from 'react';
import * as ReactDOM from 'react-dom';
import Tree from '../components/Tree/Tree';
import { fromJS, List } from "immutable";
import * as shortid from 'shortid';
import events from "../utils/events";
import * as _ from "lodash";
import { toast } from "react-toastify";
class ProductClassTree extends React.PureComponent<any, any> {

  private newCount = 1;
  constructor(props, context) {
    super(props, context);

    this.state = {
      nodes: props.nodes,
      editable: [],
      expanded: []
    }

    if (props.nodes.size > 0) {
      this.state.expanded.push(props.nodes.getIn([0, "id"]))
    }
    this.onExpand = this.onExpand.bind(this);
    this.getExtraNode = this.getExtraNode.bind(this);
    this.onFinishedEdit = this.onFinishedEdit.bind(this);
    this.onSelect = this.onSelect.bind(this);
  }

  static childContextTypes = {

  }

  getChildContext() {
    return {
    }
  }

  onExpand(expanded) {
    this.setState({ expanded });
  }

  componentWillReceiveProps({ nodes }) {
    if (nodes != this.props.nodes) {
      this.setState({ nodes: nodes })
    }
  }

  addNode(parentNode, newNode) {
    const { expanded, nodes } = this.state;
    const nodePath = this.getNodePathByValue(nodes, parentNode.value);

    this.setState({
      expanded: expanded.concat(parentNode.value),
      nodes: nodes.updateIn(nodePath.concat("children"), List(), children => {
        return children.push(fromJS(newNode))
      }),
      editable: [newNode.id]
    });
  }

  renameNode(node) {
    this.setState({
      editable: [node.value]
    });
  }

  getNodePathByValue(nodes, value) {
    let ret: any[] = null;
    nodes.forEach((node, index) => {
      if (node.get("id") == value) {
        ret = [index];
        return false;
      }
      else if (node.get("children")) {
        const childPath = this.getNodePathByValue(node.get("children"), value);
        if (childPath) {
          ret = [index, "children"].concat(childPath);
          return false;
        }
      }
    })
    return ret;
  }

  getExtraNode(node) {
    if (node.editable) return null;
    if (node.label == "商品分类" || node.label == "默认分类") return null;
    if (node.selected || node.hover) {
      const elem = [];
      elem.push(<span key="add" className="button add" onClick={() => {
        const count = this.newCount++;
        this.addNode(node, { id: shortid.generate(), text: "new node" + count })
      }} title="add node"></span>)
      elem.push(<span key="rename" className="button edit" onClick={() => {
        this.renameNode(node)
      }} title="rename"></span>)
      return elem;
    }
  }

  onFinishedEdit(node) {
    const { createProductClass, updateProductClass } = this.props;
    const { nodes } = this.state;
    const nodePath = this.getNodePathByValue(nodes, node.value);
    const parentNode = nodes.getIn(nodePath.slice(0, nodePath.length - 2));
    const repeat = parentNode.get("children", List()).findIndex(node => node.get("text") == node.label) != -1;
    toast.error("您所输入的分类名称重复，请重新输入!");  

    this.setState({
      nodes: nodes.updateIn(nodePath, oldNode => {
        return oldNode.set("text", node.label)
      }),
      editable: []
    });


    if (_.isNumber(node.value)) {
      updateProductClass({ id: node.value, text: node.label });
    }
    else {
      createProductClass(parentNode.get("id"), node.label);
    }
  }

  onSelect(node) {
    this.props.onSelect({ "id": node.value, "text": node.label, children: node.children });
  }

  converToTreeNode(nodes) {
    if (!nodes) return null;
    return nodes.map(node => {
      return {
        value: node.id, label: node.text,
        children: this.converToTreeNode(node.children)
      }
    })
  }


  render() {
    const { checked, expanded, editable, nodes } = this.state;
    return (
      <Tree nodes={this.converToTreeNode(nodes.toJS())}
        onExpand={this.onExpand}
        expanded={expanded}
        editable={editable}
        clickExpand={true}
        onSetCurNode={this.onSelect}
        onFinishedEdit={this.onFinishedEdit}
        getExtraNode={this.getExtraNode}>
      </Tree >
    );
  }
}


export default ProductClassTree;